package cn.zl.common.manage;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.Const;
import cn.zl.common.ZLConst;
import cn.zl.common.manage.data.VirtualVideoStreamData;
import cn.zl.config.ZLConfig;
import cn.zl.model.VirtualVideoStream;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class VirtualVideoStreamManage {

    private static final Logger logger = LoggerFactory.getLogger(VirtualVideoStreamManage.class);

    private final Map<String, VirtualVideoStreamData> manage = new HashMap<>();

    @Resource
    private ZLConfig config;

    public void start(VirtualVideoStream stream) {
        VirtualVideoStreamData streamData = manage.get(stream.getFileId());
        if (ObjUtil.isNotNull(streamData)) {
            logger.info("[开启-模拟视频流] 已经存在 file_id:{} app: {} stream: {}", stream.getFileId(), stream.getApp(), stream.getStream());
            return;
        }
        final VirtualVideoStreamData data = new VirtualVideoStreamData(stream);
        manage.put(stream.getFileId(), data);
        String filePath = ZLConst.VIRTUAL_VIDEO.DIR + stream.getFileId() + "." + stream.getFileType();
        String url = StrUtil.format("rtsp://{}:{}/{}/{}", "127.0.0.1", config.getZLMPort("rtsp"), stream.getApp(), stream.getStream());
        new Thread(() -> {
            try {
                List<String> command = getStrings(filePath, url);
                logger.info("[开启模拟视频流] app:{} stream:{} cmd:{}", stream.getApp(), stream.getStream(), StrUtil.join(" ", command));
                ProcessBuilder builder = new ProcessBuilder(command);
                builder.redirectErrorStream(true);
                Process process = builder.start();
                ProcessHandle handle = process.toHandle();
                data.setProcessHandle(handle);
                long pid = handle.pid();
                logger.info("[开启模拟视频流] app:{} stream:{} pid:{}", stream.getApp(), stream.getStream(), pid);
                int code = process.waitFor();
                logger.info("[关闭模拟视频流] app:{} stream:{} code:{}", stream.getApp(), stream.getStream(), code);
            } catch (IOException e) {
                logger.error("start ffmpeg error", e);
            } catch (InterruptedException e) {
                logger.error("ffmpeg Interrupted", e);
            }
        }, stream.getFileId() + "-push-thread").start();

    }

    public void stop(String fileId) {
        VirtualVideoStreamData data = manage.get(fileId);
        if (ObjUtil.isNotNull(data)) {
            ProcessHandle handle = data.getProcessHandle();
            handle.destroy();
            handle.descendants().forEach(ProcessHandle::destroy);
        }
        manage.remove(fileId);
    }

    private List<String> getStrings(String filePath, String url) {
        List<String> command = new ArrayList<>();
        command.add(config.getFfmpeg());
        command.add("-re");
        command.add("-stream_loop");
        command.add("-1");
        command.add("-i");
        command.add(filePath);
        command.add("-vcodec");
        command.add("copy");
        command.add("-acodec");
        command.add("copy");
        command.add("-f");
        command.add("rtsp");
        command.add("-rtsp_transport");
        command.add("tcp");
        command.add(url);
        return command;
    }



}
